import tkinter as tk
from tkinter import ttk, messagebox, filedialog, Menu
import keyboard
import threading
import json
import os
import sys
from tkinter import font
from pathlib import Path
import win32api
import win32gui
import win32con
from PIL import Image, ImageTk

class CommandManager:
    """命令管理器，负责加载、搜索和管理命令数据"""
    
    def __init__(self):
        self.categories = {}
        self.data_dir = Path.home() / ".programmer_assistant"
        self.data_dir.mkdir(exist_ok=True)
        self.data_file = self.data_dir / "commands.json"
        
        # 检查是否是首次启动
        self.is_first_run = not self.data_file.exists()
        self.load_commands()
        
        # 首次启动时导入默认命令
        if self.is_first_run:
            default_commands = self.get_default_commands()
            if default_commands:
                self.categories = default_commands
                self.save_commands()
                print("首次启动：已导入默认命令")
    
    def get_default_commands(self):
        """获取默认命令数据"""
        default_data = {
            "Git": [
                {
                    "command": "git clone <repository>",
                    "description": "克隆远程仓库到本地"
                },
                {
                    "command": "git add <file>",
                    "description": "将文件添加到暂存区"
                },
                {
                    "command": "git commit -m \"message\"",
                    "description": "提交暂存区的内容到本地仓库"
                },
                {
                    "command": "git push <remote> <branch>",
                    "description": "将本地分支推送到远程仓库"
                },
                {
                    "command": "git pull <remote> <branch>",
                    "description": "拉取远程分支并合并到当前分支"
                }
            ],
            "Linux": [
                {
                    "command": "ls -l",
                    "description": "以长格式显示文件和目录"
                },
                {
                    "command": "cd <directory>",
                    "description": "切换到指定目录"
                },
                {
                    "command": "mkdir <directory>",
                    "description": "创建新目录"
                },
                {
                    "command": "rm <file>",
                    "description": "删除文件"
                },
                {
                    "command": "grep <pattern> <file>",
                    "description": "在文件中搜索匹配的文本"
                }
            ],
            "Python": [
                {
                    "command": "pip install <package>",
                    "description": "安装Python包"
                },
                {
                    "command": "python -m venv <env_name>",
                    "description": "创建虚拟环境"
                },
                {
                    "command": "source <env_name>/bin/activate",
                    "description": "激活虚拟环境（Linux/macOS）"
                },
                {
                    "command": "<env_name>\\Scripts\\activate",
                    "description": "激活虚拟环境（Windows）"
                },
                {
                    "command": "pip freeze > requirements.txt",
                    "description": "导出依赖列表"
                }
            ]
        }
        return default_data
    
    def load_commands(self):
        """从文件加载命令数据"""
        try:
            if self.data_file.exists():
                with open(self.data_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    self.categories = data.get('categories', {})
        except Exception as e:
            print(f"加载命令数据失败: {e}")
            self.categories = {}
    
    def save_commands(self):
        """保存命令数据到文件"""
        try:
            data = {'categories': self.categories}
            with open(self.data_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存命令数据失败: {e}")
    
    def add_category(self, category_name):
        """添加新分类"""
        if category_name not in self.categories:
            self.categories[category_name] = []
            self.save_commands()
            return True
        return False
    
    def add_command(self, category, command, description):
        """添加新命令到指定分类"""
        if category in self.categories:
            self.categories[category].append({
                'command': command,
                'description': description
            })
            self.save_commands()
            return True
        return False
    
    def delete_category(self, category_name):
        """删除分类"""
        if category_name in self.categories:
            del self.categories[category_name]
            self.save_commands()
            return True
        return False
    
    def delete_command(self, category, command_text):
        """删除命令"""
        if category in self.categories:
            self.categories[category] = [
                cmd for cmd in self.categories[category] 
                if cmd['command'] != command_text
            ]
            self.save_commands()
            return True
        return False
    
    def search(self, query):
        """搜索命令，支持模糊搜索"""
        results = []
        query = query.lower()
        
        for category, commands in self.categories.items():
            for cmd in commands:
                # 检查命令或描述是否包含查询词，或模糊匹配
                if (query in cmd['command'].lower() or 
                    query in cmd['description'].lower() or
                    self._fuzzy_match(cmd['command'], query) or
                    self._fuzzy_match(cmd['description'], query)):
                    results.append({
                        'category': category,
                        'command': cmd['command'],
                        'description': cmd['description']
                    })
        
        return results
    
    def _fuzzy_match(self, text, pattern):
        """简单的模糊匹配算法"""
        pattern = pattern.lower()
        text = text.lower()
        index = 0
        
        for char in pattern:
            index = text.find(char, index)
            if index == -1:
                return False
            index += 1
        
        return True
    
    def import_commands(self, file_path):
        """从文件导入命令"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
                
                for category, commands in data.items():
                    if category not in self.categories:
                        self.categories[category] = []
                    
                    for cmd in commands:
                        if isinstance(cmd, dict) and 'command' in cmd and 'description' in cmd:
                            self.categories[category].append({
                                'command': cmd['command'],
                                'description': cmd['description']
                            })
            
            self.save_commands()
            return True, f"成功导入 {len(data)} 个分类"
        except Exception as e:
            return False, f"导入失败: {str(e)}"
    
    def export_commands(self, file_path, categories=None):
        """导出命令到文件"""
        try:
            export_data = {}
            
            if categories:
                for category in categories:
                    if category in self.categories:
                        export_data[category] = self.categories[category]
            else:
                export_data = self.categories
            
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(export_data, f, ensure_ascii=False, indent=2)
            
            return True, f"成功导出 {len(export_data)} 个分类"
        except Exception as e:
            return False, f"导出失败: {str(e)}"


class ProgrammerAssistant:
    """程序员助手主应用"""
    
    def __init__(self, root):
        self.root = root
        self.root.title("程序员助手")
        self.root.geometry("750x500")
        self.root.resizable(True, True)
        
        # 确保中文正常显示
        self.default_font = font.nametofont("TkDefaultFont")
        self.default_font.configure(family="SimHei", size=10)
        self.root.option_add("*Font", self.default_font)
        
        # 命令管理器
        self.command_manager = CommandManager()
        
        # 主题设置
        self.dark_mode = False
        self.setup_themes()
        
        # 窗口初始状态为隐藏
        self.root.withdraw()
        
        # 热键设置
        self.hotkey = 'ctrl + alt+space'
        
        # 系统托盘图标
        self.is_tray_visible = False
        self.tray_icon = None
        self.create_tray_icon()
        
        # 绑定关闭事件到隐藏函数
        self.root.protocol("WM_DELETE_WINDOW", self.hide_window)
        
        # 创建界面
        self.create_ui()
        
        # 启动热键监听线程
        self.start_hotkey_listener()
        
        # 设置开机自启动
        self.setup_autostart()
    
    def setup_themes(self):
        """设置主题配置"""
        self.light_theme = {
            'bg': '#f9fafb',
            'frame_bg': '#f9fafb',
            'entry_bg': 'white',
            'entry_fg': 'black',
            'tree_bg': 'white',
            'tree_fg': 'black',
            'tree_head_bg': '#e5e7eb',
            'tree_head_fg': 'black',
            'status_bg': '#f3f4f6',
            'status_fg': '#6b7280'
        }
        
        self.dark_theme = {
            'bg': '#1e1e1e',
            'frame_bg': '#2d2d2d',
            'entry_bg': '#3c3c3c',
            'entry_fg': 'white',
            'tree_bg': '#2d2d2d',
            'tree_fg': 'white',
            'tree_head_bg': '#4e4e4e',
            'tree_head_fg': 'white',
            'status_bg': '#333333',
            'status_fg': '#a9a9a9'
        }
    
    def create_ui(self):
        """创建用户界面"""
        # 创建样式
        self.style = ttk.Style()
        
        # 顶部搜索区域
        self.search_frame = tk.Frame(self.root, padx=20, pady=15)
        self.search_frame.pack(fill=tk.X)
        
        # 结果展示区域
        self.result_frame = tk.Frame(self.root, padx=20, pady=10)
        self.result_frame.pack(fill=tk.BOTH, expand=True)
        
        # 底部状态栏
        self.status_frame = tk.Frame(self.root, height=30)
        self.status_frame.pack(fill=tk.X, side=tk.BOTTOM)
        
        # 创建菜单栏
        self.create_menu()
        
        # 应用初始主题
        initial_theme = self.light_theme if not self.dark_mode else self.dark_theme
        
        # 搜索框组件
        search_label = tk.Label(self.search_frame, text="搜索:", 
                              bg=initial_theme['frame_bg'], 
                              font=("SimHei", 12))
        search_label.pack(side=tk.LEFT, padx=(0, 10))
        
        self.search_var = tk.StringVar()
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var, 
                                    font=("SimHei", 12), width=40,
                                    bg=initial_theme['entry_bg'], relief=tk.FLAT, bd=1,
                                    highlightthickness=1, highlightbackground="#e5e7eb",
                                    highlightcolor="#3b82f6")
        self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, ipady=5)
        self.search_entry.bind("<KeyRelease>", self.search_commands)
        
        # 表格组件
        columns = ("分类", "命令", "说明")
        self.tree = ttk.Treeview(self.result_frame, columns=columns, show="headings", height=15)
        
        # 设置列宽和标题
        self.tree.column("分类", width=120, anchor=tk.W)
        self.tree.column("命令", width=250, anchor=tk.W)
        self.tree.column("说明", width=300, anchor=tk.W)
        
        for col in columns:
            self.tree.heading(col, text=col)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(self.result_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscroll=scrollbar.set)
        
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.tree.pack(fill=tk.BOTH, expand=True)
        
        # 绑定双击事件（复制命令）
        self.tree.bind("<Double-1>", self.copy_command)
        
        # 绑定右键菜单
        self.create_context_menu()
        
        # 创建状态栏标签（使用初始主题）
        self.status_label = tk.Label(self.status_frame, 
                                   text=f"快捷键: {self.hotkey} | 双击命令复制到剪贴板 | 托盘图标可显示/退出", 
                                   bg=initial_theme['status_bg'], 
                                   fg=initial_theme['status_fg'], 
                                   font=("SimHei", 9))
        self.status_label.pack(side=tk.LEFT, padx=10, pady=5)
        
        # 应用当前主题（更新所有组件样式）
        self.apply_theme()
        
        # 初始化显示所有命令
        self.display_all_commands()
        
        # 首次启动提示
        if self.command_manager.is_first_run:
            messagebox.showinfo("欢迎使用", "首次启动已为您导入默认命令。\n您可以通过菜单添加更多命令或导入自定义命令文件。")
    
    def create_menu(self):
        """创建菜单栏"""
        menubar = Menu(self.root)
        
        # 文件菜单
        file_menu = Menu(menubar, tearoff=0)
        file_menu.add_command(label="导入命令", command=self.import_commands)
        file_menu.add_command(label="导出命令", command=self.export_commands)
        file_menu.add_separator()
        file_menu.add_command(label="退出", command=self.exit_app)
        menubar.add_cascade(label="文件", menu=file_menu)
        
        # 编辑菜单
        edit_menu = Menu(menubar, tearoff=0)
        edit_menu.add_command(label="添加分类", command=self.add_category)
        edit_menu.add_command(label="添加命令", command=self.add_command)
        edit_menu.add_separator()
        edit_menu.add_command(label="删除选中分类", command=self.delete_selected_category)
        edit_menu.add_command(label="删除选中命令", command=self.delete_selected_command)
        menubar.add_cascade(label="编辑", menu=edit_menu)
        
        # 主题菜单
        theme_menu = Menu(menubar, tearoff=0)
        theme_menu.add_command(label="切换深色模式", command=self.toggle_dark_mode)
        menubar.add_cascade(label="主题", menu=theme_menu)
        
        # 帮助菜单
        help_menu = Menu(menubar, tearoff=0)
        help_menu.add_command(label="关于", command=self.show_about)
        menubar.add_cascade(label="帮助", menu=help_menu)
        
        self.root.config(menu=menubar)
    
    def create_context_menu(self):
        """创建右键菜单"""
        self.context_menu = Menu(self.root, tearoff=0)
        self.context_menu.add_command(label="复制命令", command=self.copy_selected_command)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="删除选中分类", command=self.delete_selected_category)
        self.context_menu.add_command(label="删除选中命令", command=self.delete_selected_command)
        
        self.tree.bind("<Button-3>", self.show_context_menu)
    
    def show_context_menu(self, event):
        """显示右键菜单"""
        # 选择点击的项
        item = self.tree.identify_row(event.y)
        if item:
            self.tree.selection_set(item)
            self.context_menu.post(event.x_root, event.y_root)
    
    def apply_theme(self):
        """应用当前主题"""
        theme = self.dark_theme if self.dark_mode else self.light_theme
        
        self.root.configure(bg=theme['bg'])
        self.search_frame.configure(bg=theme['frame_bg'])
        self.result_frame.configure(bg=theme['frame_bg'])
        self.status_frame.configure(bg=theme['status_bg'])
        self.status_label.configure(bg=theme['status_bg'], fg=theme['status_fg'])
        
        self.search_entry.configure(bg=theme['entry_bg'], fg=theme['entry_fg'],
                                   highlightbackground=theme['frame_bg'],
                                   highlightcolor='#3b82f6')
        
        # 配置Treeview样式
        self.style.configure("Treeview", 
                            background=theme['tree_bg'],
                            foreground=theme['tree_fg'],
                            fieldbackground=theme['tree_bg'],
                            rowheight=25)
        
        self.style.configure("Treeview.Heading", 
                            background=theme['tree_head_bg'],
                            foreground=theme['tree_head_fg'],
                            font=("SimHei", 10, "bold"),
                            relief="flat")
        
        # 刷新Treeview样式
        for item in self.tree.get_children():
            self.tree.item(item, tags=("row",))
        
        self.style.map("Treeview", 
                      background=[('selected', '#3b82f6' if not self.dark_mode else '#1e40af')])
    
    def display_all_commands(self):
        """显示所有命令"""
        # 清空现有项
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 添加所有命令
        for category, commands in self.command_manager.categories.items():
            for cmd in commands:
                self.tree.insert("", tk.END, values=(category, cmd['command'], cmd['description']))
    
    def search_commands(self, event=None):
        """搜索命令"""
        query = self.search_var.get().strip()
        if not query:
            self.display_all_commands()
            return
        
        # 执行搜索
        results = self.command_manager.search(query)
        
        # 清空现有项
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 添加搜索结果
        for result in results:
            self.tree.insert("", tk.END, values=(
                result['category'], 
                result['command'], 
                result['description']
            ))
    
    def copy_command(self, event):
        """复制选中的命令到剪贴板"""
        selected_item = self.tree.selection()
        if not selected_item:
            return
        
        item = self.tree.item(selected_item[0])
        command = item["values"][1]  # 命令在第二列
        
        self.root.clipboard_clear()
        self.root.clipboard_append(command)
        
        # 显示提示
        messagebox.showinfo("提示", f"已复制命令: {command}")
    
    def copy_selected_command(self):
        """从右键菜单复制命令"""
        self.copy_command(None)
    
    def delete_selected_category(self):
        """删除选中的分类"""
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showinfo("提示", "请先选择一个分类下的命令")
            return
        
        item = self.tree.item(selected_item[0])
        category = item["values"][0]  # 分类在第一列
        
        if messagebox.askyesno("确认删除", f"确定要删除分类 '{category}' 及其所有命令吗？"):
            if self.command_manager.delete_category(category):
                messagebox.showinfo("成功", f"分类 '{category}' 已删除")
                self.display_all_commands()
            else:
                messagebox.showerror("错误", "删除分类失败")
    
    def delete_selected_command(self):
        """删除选中的命令"""
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showinfo("提示", "请先选择一个命令")
            return
        
        item = self.tree.item(selected_item[0])
        category = item["values"][0]  # 分类在第一列
        command = item["values"][1]   # 命令在第二列
        
        if messagebox.askyesno("确认删除", f"确定要删除命令 '{command}' 吗？"):
            if self.command_manager.delete_command(category, command):
                messagebox.showinfo("成功", "命令已删除")
                self.display_all_commands()
            else:
                messagebox.showerror("错误", "删除命令失败")
    
    def toggle_visibility(self):
        """切换窗口可见性"""
        if self.root.state() == "withdrawn" or self.root.state() == "iconic":
            self.show_window()
        else:
            self.hide_window()
    
    def create_tray_icon(self):
        """创建系统托盘图标"""
        try:
            # 尝试加载图标
            icon_path = "icon.ico"  # 默认路径
            
            # 检查是否在打包环境中
            if getattr(sys, 'frozen', False):
                icon_path = os.path.join(sys._MEIPASS, 'icon.ico')
            
            # 确保图标存在
            if not os.path.exists(icon_path):
                # 创建临时图标
                import tempfile
                with tempfile.NamedTemporaryFile(suffix='.ico', delete=False) as f:
                    icon_path = f.name
                    # 创建一个简单的图标（实际应用中应替换为真实图标）
                    with open(icon_path, 'wb') as icon_file:
                        # 这里只是一个占位符，实际需要一个有效的.ico文件
                        icon_file.write(b'\x00' * 1024)
            
            # 创建托盘窗口
            message_map = {
                win32con.WM_DESTROY: self.on_destroy,
                win32con.WM_COMMAND: self.on_command,
                win32con.WM_USER+20: self.on_notify,
            }
            
            # 注册窗口类
            wc = win32gui.WNDCLASS()
            hinst = wc.hInstance = win32gui.GetModuleHandle(None)
            wc.lpszClassName = "PythonTaskbar"
            wc.lpfnWndProc = message_map  # 可以指定为默认处理程序
            class_atom = win32gui.RegisterClass(wc)
            
            # 创建窗口
            style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
            self.hwnd = win32gui.CreateWindow(
                class_atom, "Taskbar", style, 0, 0, 
                win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 
                0, 0, hinst, None
            )
            win32gui.UpdateWindow(self.hwnd)
            
            # 加载图标
            icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
            try:
                hicon = win32gui.LoadImage(
                    hinst, icon_path, win32con.IMAGE_ICON, 0, 0, icon_flags
                )
            except:
                hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
            
            # 创建托盘图标
            flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP
            nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "程序员助手")
            win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid)
            
            # 创建托盘菜单
            self.menu = win32gui.CreatePopupMenu()
            self.add_menu_item(self.menu, "显示", 1023)
            self.add_menu_item(self.menu, "退出", 1024)
            
            self.is_tray_visible = True
        
        except Exception as e:
            print(f"创建托盘图标失败: {e}")
            self.is_tray_visible = False
    
    def add_menu_item(self, menu, label, id):
        """向托盘菜单添加项"""
        win32gui.AppendMenu(menu, win32con.MF_STRING, id, label)
    
    def on_notify(self, hwnd, msg, wparam, lparam):
        """处理托盘图标通知消息"""
        if lparam == win32con.WM_LBUTTONDBLCLK:
            self.show_window()
        elif lparam == win32con.WM_RBUTTONUP:
            self.show_tray_menu()
        return True
    
    def show_tray_menu(self):
        """显示托盘菜单"""
        if not self.is_tray_visible:
            return
        
        pos = win32gui.GetCursorPos()
        win32gui.SetForegroundWindow(self.hwnd)
        win32gui.TrackPopupMenu(
            self.menu, 
            win32con.TPM_LEFTALIGN, 
            pos[0], pos[1], 
            0, self.hwnd, None
        )
        win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)
    
    def on_command(self, hwnd, msg, wparam, lparam):
        """处理菜单命令"""
        id = win32gui.LOWORD(wparam)
        if id == 1023:  # 显示
            self.show_window()
        elif id == 1024:  # 退出
            self.exit_app()
    
    def on_destroy(self, hwnd, msg, wparam, lparam):
        """处理窗口销毁"""
        if self.is_tray_visible:
            nid = (self.hwnd, 0)
            win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
            win32gui.PostQuitMessage(0)
        return True
    
    def hide_window(self, event=None):
        """隐藏窗口到托盘"""
        self.root.withdraw()
        if self.is_tray_visible:
            self.show_tray_tooltip("程序员助手已最小化到托盘")
    
    def show_window(self, event=None):
        """显示窗口"""
        self.root.deiconify()
        self.root.lift()
        self.root.focus_force()
    
    def show_tray_tooltip(self, text):
        """显示托盘提示"""
        if self.is_tray_visible:
            nid = (self.hwnd, 0, win32gui.NIF_TIP, 0, 0, text)
            win32gui.Shell_NotifyIcon(win32gui.NIM_MODIFY, nid)
    
    def exit_app(self, event=None):
        """退出应用程序"""
        if messagebox.askyesno("确认退出", "确定要退出程序员助手吗？"):
            if self.is_tray_visible:
                nid = (self.hwnd, 0)
                win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
                win32gui.DestroyWindow(self.hwnd)
            
            self.root.destroy()
            sys.exit(0)
    
    def start_hotkey_listener(self):
        """启动热键监听线程"""
        def hotkey_listener():
            try:
                keyboard.add_hotkey(self.hotkey, self.toggle_visibility)
                keyboard.wait()
            except Exception as e:
                print(f"热键监听错误: {e}")
        
        thread = threading.Thread(target=hotkey_listener, daemon=True)
        thread.start()
    
    def setup_autostart(self):
        """设置开机自启动"""
        try:
            if sys.platform.startswith('win'):
                # Windows系统
                startup_folder = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup')
                shortcut_path = os.path.join(startup_folder, 'ProgrammerAssistant.lnk')
                
                if not os.path.exists(shortcut_path):
                    try:
                        import winshell
                        with winshell.shortcut(shortcut_path) as shortcut:
                            shortcut.path = sys.executable
                            shortcut.arguments = os.path.abspath(sys.argv[0])
                            shortcut.description = "程序员助手"
                    except ImportError:
                        # 如果没有winshell模块，使用注册表方法
                        import winreg
                        key = winreg.OpenKey(
                            winreg.HKEY_CURRENT_USER, 
                            r"Software\Microsoft\Windows\CurrentVersion\Run", 
                            0, 
                            winreg.KEY_SET_VALUE
                        )
                        winreg.SetValueEx(key, "ProgrammerAssistant", 0, winreg.REG_SZ, f'"{sys.executable}" "{os.path.abspath(sys.argv[0])}"')
                        winreg.CloseKey(key)
            
            elif sys.platform.startswith('linux'):
                # Linux系统
                autostart_dir = os.path.expanduser('~/.config/autostart/')
                os.makedirs(autostart_dir, exist_ok=True)
                desktop_file = os.path.join(autostart_dir, 'programmer_assistant.desktop')
                
                if not os.path.exists(desktop_file):
                    with open(desktop_file, 'w') as f:
                        f.write(f"""[Desktop Entry]
Type=Application
Exec={sys.executable} {os.path.abspath(sys.argv[0])}
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name=Programmer Assistant
Comment=程序员助手""")
        except Exception as e:
            print(f"设置开机自启动失败: {e}")
    
    def toggle_dark_mode(self):
        """切换深色模式"""
        self.dark_mode = not self.dark_mode
        self.apply_theme()
    
    def import_commands(self):
        """导入命令"""
        file_path = filedialog.askopenfilename(
            title="选择命令文件",
            filetypes=[("JSON 文件", "*.json"), ("所有文件", "*.*")]
        )
        
        if file_path:
            success, message = self.command_manager.import_commands(file_path)
            if success:
                messagebox.showinfo("成功", message)
                self.display_all_commands()
            else:
                messagebox.showerror("错误", message)
    
    def export_commands(self):
        """导出命令"""
        file_path = filedialog.asksaveasfilename(
            title="保存命令文件",
            defaultextension=".json",
            filetypes=[("JSON 文件", "*.json"), ("所有文件", "*.*")]
        )
        
        if file_path:
            success, message = self.command_manager.export_commands(file_path)
            if success:
                messagebox.showinfo("成功", message)
            else:
                messagebox.showerror("错误", message)
    
    def add_category(self):
        """添加新分类"""
        category_window = tk.Toplevel(self.root)
        category_window.title("添加分类")
        category_window.geometry("300x150")
        category_window.resizable(False, False)
        category_window.transient(self.root)
        category_window.grab_set()
        
        frame = tk.Frame(category_window, padx=20, pady=20)
        frame.pack(fill=tk.BOTH, expand=True)
        
        label = tk.Label(frame, text="分类名称:")
        label.pack(anchor=tk.W, pady=(0, 5))
        
        entry = tk.Entry(frame, width=30)
        entry.pack(fill=tk.X, pady=(0, 15))
        entry.focus_set()
        
        button_frame = tk.Frame(frame)
        button_frame.pack(fill=tk.X)
        
        def save_category():
            category_name = entry.get().strip()
            if category_name:
                if self.command_manager.add_category(category_name):
                    messagebox.showinfo("成功", f"分类 '{category_name}' 已添加")
                    category_window.destroy()
                    self.display_all_commands()
                else:
                    messagebox.showerror("错误", f"分类 '{category_name}' 已存在")
        
        save_btn = tk.Button(button_frame, text="保存", command=save_category)
        save_btn.pack(side=tk.RIGHT, padx=(5, 0))
        
        cancel_btn = tk.Button(button_frame, text="取消", command=category_window.destroy)
        cancel_btn.pack(side=tk.RIGHT)
    
    def add_command(self):
        """添加新命令"""
        if not self.command_manager.categories:
            messagebox.showinfo("提示", "请先添加分类")
            return
        
        command_window = tk.Toplevel(self.root)
        command_window.title("添加命令")
        command_window.geometry("400x250")
        command_window.resizable(False, False)
        command_window.transient(self.root)
        command_window.grab_set()
        
        frame = tk.Frame(command_window, padx=20, pady=20)
        frame.pack(fill=tk.BOTH, expand=True)
        
        # 分类选择
        label_category = tk.Label(frame, text="选择分类:")
        label_category.pack(anchor=tk.W, pady=(0, 5))
        
        category_var = tk.StringVar()
        categories = list(self.command_manager.categories.keys())
        if categories:
            category_var.set(categories[0])
        
        category_menu = tk.OptionMenu(frame, category_var, *categories)
        category_menu.pack(fill=tk.X, pady=(0, 10))
        
        # 命令输入
        label_command = tk.Label(frame, text="命令:")
        label_command.pack(anchor=tk.W, pady=(0, 5))
        
        command_entry = tk.Entry(frame, width=40)
        command_entry.pack(fill=tk.X, pady=(0, 10))
        command_entry.focus_set()
        
        # 说明输入
        label_desc = tk.Label(frame, text="说明:")
        label_desc.pack(anchor=tk.W, pady=(0, 5))
        
        desc_entry = tk.Entry(frame, width=40)
        desc_entry.pack(fill=tk.X, pady=(0, 15))
        
        button_frame = tk.Frame(frame)
        button_frame.pack(fill=tk.X)
        
        def save_command():
            category = category_var.get()
            command = command_entry.get().strip()
            description = desc_entry.get().strip()
            
            if command and description:
                # 检查命令是否已存在
                for cmd in self.command_manager.categories[category]:
                    if cmd['command'] == command:
                        messagebox.showerror("错误", f"命令 '{command}' 已存在于分类 '{category}' 中")
                        return
                
                if self.command_manager.add_command(category, command, description):
                    messagebox.showinfo("成功", "命令已添加")
                    command_window.destroy()
                    self.display_all_commands()
                else:
                    messagebox.showerror("错误", "添加命令失败")
        
        save_btn = tk.Button(button_frame, text="保存", command=save_command)
        save_btn.pack(side=tk.RIGHT, padx=(5, 0))
        
        cancel_btn = tk.Button(button_frame, text="取消", command=command_window.destroy)
        cancel_btn.pack(side=tk.RIGHT)
    
    def show_about(self):
        """显示关于对话框"""
        about_window = tk.Toplevel(self.root)
        about_window.title("关于")
        about_window.geometry("300x200")
        about_window.resizable(False, False)
        about_window.transient(self.root)
        about_window.grab_set()
        
        frame = tk.Frame(about_window, padx=20, pady=20)
        frame.pack(fill=tk.BOTH, expand=True)
        
        title_label = tk.Label(frame, text="程序员助手", font=("SimHei", 16, "bold"))
        title_label.pack(pady=(0, 10))
        
        version_label = tk.Label(frame, text="版本 1.0.0", font=("SimHei", 10))
        version_label.pack(pady=(0, 5))
        
        desc_label = tk.Label(frame, text="程序员助手是一个命令行工具集合\n用于快速查找和复制常用命令", font=("SimHei", 10))
        desc_label.pack(pady=(0, 10))
        
        close_btn = tk.Button(frame, text="关闭", command=about_window.destroy)
        close_btn.pack(side=tk.RIGHT)

if __name__ == "__main__":
    root = tk.Tk()
    app = ProgrammerAssistant(root)
    root.mainloop()    